package com.logger;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

import org.apache.commons.io.filefilter.IOFileFilter;

import com.fmk.utils.FileUtils;
import com.fmk.utils.StringUtils;

public final class LogFiles extends ArrayList<LogFile> {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public LogFiles() {
    }

    public void loadUserFiles(final String directoryPath) {
        final File[] listOfFiles = LogFiles.listFiles(directoryPath);
        this.loadUserFiles(listOfFiles);
    }

    public static File[] listFiles(final String directoryPath) {
        final IOFileFilter filenameFilter = new IOFileFilter() {

            public boolean accept(final File dir, final String name) {
                // final boolean isUserLogFile = LogFile.isUserLogFile(name);
                // if (isUserLogFile) {
                // return true;
                // }
                // if (name.indexOf(".") == -1) {
                // return true;
                // }
                return false;
            }

            public boolean accept(final File file) {
                if (file.isDirectory()) {
                    return true;
                }
                final boolean isUserLogFile = LogFile.isUserLogFile(file);
                if (isUserLogFile) {
                    return true;
                }
                return false;
            }
        };
        final File[] listOfFiles = FileUtils.listAllFiles(new File(directoryPath), filenameFilter);
        return listOfFiles;
    }

    public void loadUserFiles(final File[] listOfFiles) {

        for (final File file : listOfFiles) {
            Scanner scanner;
            final LogFile myLogFile = new LogFile(file);
            try {
                scanner = new Scanner(file);
                LogQuery logQuery = null;
                LogTransaction logTransaction = null;
                while (scanner.hasNext()) {
                    final String line = scanner.nextLine();
                    if (!StringUtils.isEmptyLine(line)) {
                        final EnumUserLogLineType lineType = EnumUserLogLineType.getLineType(line);
                        switch (lineType) {
                        case QUERY_START_1:
                            if (logQuery != null) {
                                final String queryContent = logQuery.getQueryContent().toString();
                                if ("".equals(queryContent)) {
                                    final String fileName = logQuery.getQueryfile();
                                    final String qeryName = logQuery.getQueryName();
                                    final StringBuilder sbMsgError = new StringBuilder();
                                    sbMsgError.append(fileName);
                                    sbMsgError.append(".");
                                    sbMsgError.append(qeryName);
                                    sbMsgError.append(" hasn't content!");
                                    logQuery.setMsgError(sbMsgError.toString());
                                }
                            }
                            if (logTransaction != null && logTransaction.isInitialized()) {
                                logQuery = new LogQuery(myLogFile, logTransaction).init(line);
                            } else {
                                logQuery = new LogQuery(myLogFile).init(line);
                            }
                            continue;
                        case QUERY_EXECUTE:
                            if (logQuery != null) {
                                final String _fileName = LogQuery.setFileName(line);
                                final String _qeryName = LogQuery.setQueryName(line);
                                final String fileName = logQuery.getQueryfile();
                                final String qeryName = logQuery.getQueryName();
                                if (_fileName.equals(fileName) && _qeryName.equals(qeryName)) {
                                    continue;
                                }
                            }
                            if (logTransaction != null && logTransaction.isInitialized()) {
                                logQuery = new LogQuery(myLogFile, logTransaction).init(line);
                            } else {
                                logQuery = new LogQuery(myLogFile).init(line);
                            }
                            continue;

                        case QUERY_START_2:
                            if (logQuery == null) {
                                if (logTransaction != null && logTransaction.isInitialized()) {
                                    logQuery = new LogQuery(myLogFile, logTransaction).init(line);
                                } else {
                                    logQuery = new LogQuery(myLogFile).init(line);
                                }
                            } else if (logQuery.getConstructionTime() != null) {
                                if (logTransaction != null && logTransaction.isInitialized()) {
                                    logQuery = new LogQuery(myLogFile, logTransaction).init(line);
                                } else {
                                    logQuery = new LogQuery(myLogFile).init(line);
                                }
                            }
                            continue;
                        case QUERY_RAW_QUERY:
                            if (logTransaction != null && logTransaction.isInitialized()) {
                                logQuery = new LogQuery(myLogFile, logTransaction).init(line);
                            } else {
                                logQuery = new LogQuery(myLogFile).init(line);
                            }
                            logQuery.setRawQuery(line);
                            continue;
                        case QUERY_CONSTRUCTION_TIME:
                            if (logQuery != null && logQuery.getConstructionTime() == null) {
                                logQuery.setConstructionTime(line);
                            }
                            continue;
                        case UNKNOWN:
                            if (logQuery != null && logQuery.isInitialized()) {
                                if (logQuery.getConstructionTime() == null) {
                                    final StringBuilder queryContent = logQuery.getQueryContent();
                                    if (queryContent.toString().length() != 0) {
                                        queryContent.append(StringUtils.Constants.CRLF);
                                    }
                                    queryContent.append(line);
                                    continue;
                                }
                            }
                            // System.err.println("---------------------------------->"
                            // + line);
                            continue;
                        case QUERY_ROWS_NUMBER_AFFECTED:
                            if (logQuery != null && logQuery.getRowsNumber() == -1) {
                                logQuery.setRowsNumber(line);
                            }
                            continue;
                        case QUERY_ELAPSED_TIME:
                            if (logQuery != null && logQuery.getExecutionTime() == -1) {
                                logQuery.setElapsedTime(line);
                            }
                            continue;
                        case QUERY_ROWS_NUMBER_ELAPSED_TIME:
                            if (logQuery != null && logQuery.getRowsNumber() == -1) {
                                logQuery.setRowsNumber(line);
                                logQuery.setElapsedTime(line);
                            }
                            continue;
                        case QUERY_CONSTRUCTION_TIME_EXECUTION_TIME_ROWS_NUMBER:
                            if (logQuery != null && logQuery.getRowsNumber() != -1) {
                                logQuery.setConstructionTime(line);
                                logQuery.setElapsedTime(line);
                                logQuery.setRowsNumber(line);
                            }

                            continue;
                        case TRANSACTION_BEGIN:
                            if (logTransaction != null && logTransaction.isInitialized()) {
                                final long newId = LogTransaction.setId(line);
                                final StringBuilder sbError = new StringBuilder();
                                sbError.append("Transaction[");
                                sbError.append(newId);
                                sbError.append("] try to begin while another was started before[");
                                sbError.append(logTransaction.getId());
                                sbError.append("]");
                                logTransaction.setMsgError(sbError.toString());
                            }
                            logTransaction = new LogTransaction(myLogFile).init(line);
                            continue;
                        case TRANSACTION_COMMIT:
                            if (logTransaction != null && logTransaction.isInitialized()) {
                                final long newId = LogTransaction.setId(line);
                                final long oldId = logTransaction.getId();
                                if (new Long(oldId).equals(new Long(newId))) {
                                    logTransaction.setCloseDateTime(line);
                                    logTransaction.setCommit(true);
                                } else {
                                    boolean beginFound = false;
                                    for (final LogTransaction currTransaction : myLogFile.getListLogTransaction()) {
                                        final long currId = currTransaction.getId();
                                        if (new Long(currId).equals(new Long(newId))) {
                                            currTransaction.setCloseDateTime(line);
                                            currTransaction.setCommit(true);
                                            beginFound = true;
                                            final StringBuilder sbMsgError = new StringBuilder();
                                            sbMsgError.append("transaction [");
                                            sbMsgError.append(newId);
                                            sbMsgError.append("] overlapp with [");
                                            sbMsgError.append(oldId);
                                            sbMsgError.append("]");
                                            currTransaction.setMsgError(sbMsgError.toString());
                                            break;
                                        }
                                    }
                                    if (!beginFound) {
                                        System.err.println("transaction has no begin!![" + newId + "]");
                                    }
                                }
                                logTransaction = null;
                            }
                            continue;
                        case TRANSACTION_ROLL_BACK:
                            if (logTransaction != null && logTransaction.isInitialized()) {
                                final long newId = LogTransaction.setId(line);
                                final long oldId = logTransaction.getId();
                                if (new Long(oldId).equals(new Long(newId))) {
                                    logTransaction.setCloseDateTime(line);
                                    logTransaction.setCommit(false);
                                } else {
                                    boolean beginFound = false;
                                    for (final LogTransaction currTransaction : myLogFile.getListLogTransaction()) {
                                        final long currId = currTransaction.getId();
                                        if (new Long(currId).equals(new Long(newId))) {
                                            currTransaction.setCloseDateTime(line);
                                            currTransaction.setCommit(true);
                                            beginFound = true;
                                            final StringBuilder sbMsgError = new StringBuilder();
                                            sbMsgError.append("transaction [");
                                            sbMsgError.append(newId);
                                            sbMsgError.append("] overlapp with [");
                                            sbMsgError.append(oldId);
                                            sbMsgError.append("]");
                                            currTransaction.setMsgError(sbMsgError.toString());
                                            break;
                                        }
                                    }
                                    if (!beginFound) {
                                        System.err.println("transaction has no begin!![" + newId + "]");
                                    }
                                }
                                logTransaction = null;
                            }
                            continue;
                        default:
                            break;
                        }
                    }

                }
            } catch (final FileNotFoundException e) {
            }
            this.add(myLogFile);
        }

    }

    public static void main(final String[] args) {

    }

    @Override
    public String toString() {
        final StringBuilder sbString = new StringBuilder();
        for (final LogFile logFile : this) {
            sbString.append(StringUtils.Constants.CRLF);
            sbString.append(logFile);
        }
        return sbString.toString();
    }
}
